<?php

namespace App\Service\Pay;

use App\Models\Bank;
use Carbon\Carbon;
use Illuminate\Support\Facades\Http;
use Exception;

class ZfPayService extends PayService implements Pay
{
    /**
     * 充值通知地址
     * @var string
     */
    protected string $pay_notify_url = '/api/v1/hxpay_recharge';

    /**
     * 代付通知地址
     * @var string
     */
    protected string $withdrawal_notify_url = '/api/v1/hxpay_withdrawal';


    //充值
    public function recharge($attach = [])
    {
        try {
            $this->setReturnUrl();
            $param = [
                'userid' => $this->merchant,
                'notifyurl' => url($this->pay_notify_url),
                'orderid' => $this->order->no,
                'type' => $this->pay_code,
                'amount' => round($this->order->amount / 100),
            ];
            $param['sign'] = $this->sign($param, $this->pay_key);
            $response = Http::asJson()->post($this->pay_url, $param);
            $result = json_decode($response->body(), true);
            $this->order->param = json_encode($param, JSON_UNESCAPED_UNICODE);
            $this->order->response = json_encode($result, JSON_UNESCAPED_UNICODE);
            if (isset($result['success']) && $result['success'] == 1) {
                $this->order->payment_no = $result['ticket'];
                $this->order->save();
                return $result['pageurl'];
            }
            $this->rechargeFail();
            return false;
        } catch (Exception $exception) {
            $error_message = json_encode(['msg' => $exception->getMessage(), 'file' => $exception->getFile(), 'line' => $exception->getLine()], JSON_UNESCAPED_UNICODE);
            $this->rechargeFail($error_message);
            return false;
        }
    }

    public function withdrawal()
    {
        try {
            $card = json_decode($this->order->card, true);
            $bank = Bank::getBank($card['bank_id']);
            $bank_code = $bank['zf_code'];
            $bank_name = $bank['zf_name'];

            $param = [
                'userid' => $this->merchant,
                'notifyurl' => url($this->withdrawal_notify_url),
                'orderid' => $this->order->no,
                'type' => "bank",
                'amount' => round($this->order->actual_amount / 100),
            ];
            $param['sign'] = $this->sign($param, $this->withdrawal_key);
            $payload = [
                'cardname' => strtoupper($card['username']),		//收款人姓名  玩家在绑定银行信息时，输入姓名必须是英文字母，不能输入带符号的越南文姓名 否则代付订单不能处理  特别需要注意
                'cardno' => $card['number'],			//收款卡号
                'bankid' => $bank_code,				//银行编号  //见下附录2
                'bankname' => $bank_name,		//银行名称  //如果附录2中不存在，直接赋值银行名称
            ];
            $param['payload'] = json_encode($payload);
            $response = Http::asJson()->post($this->withdrawal_url, $param);
            $result = json_decode($response->body(), true);
            $result = is_array($result) ? $result : [];
            //记录入参跟响应
            $state = isset($result['success']) && $result['success'] == 1;
            $this->withdrawalCallback($param, $result, $result['ticket'] ?? '', $state);
            $this->order->save();
        } catch (Exception $exception) {
            $this->withdrawalCallback([], ['msg' => $exception->getMessage(), 'file' => $exception->getFile(), 'line' => $exception->getLine()], '', false);
        }
    }


    /**
     * 签名
     * @param $data
     * @param $secret
     * @return string
     */
    protected function sign($data, $secret): string
    {
        /*
        ksort($data);
        $str = '';
        foreach ($data as $key => $val) {
            if ($val != null) {
                $str .= $key . '=' . $val . '&';
            }
        }
        return strtolower(md5($str . 'key=' . $secret));
        */
        return md5($secret . $data['orderid'] . $data['amount']);
    }

    /**
     * 验签
     * @param array $params
     * @param string $type
     * @return bool
     */
    public function checkSign(array $params, string $type): bool
    {
        $sign = $params['sign'];
        if($type == 'pay'){
            $newsign = md5($this->pay_key . $params['orderid'] . $params['payamount']);
        }else{
            $newsign = md5($this->pay_key . $params['orderid'] . $params['amount']);
        }


        return $sign == $newsign;
    }

}
